package com.sdhs.analyze.service.monitor;


import com.alibaba.fastjson.JSON;
import com.sdhs.analyze.bean.DicNodeType;
import com.sdhs.analyze.bean.InfoNodeStatus;
import com.sdhs.analyze.bean.monitorinfo.GantryMonitorInfo;
import com.sdhs.analyze.bean.network.NetWork;
import com.sdhs.analyze.bean.org.OrgInfo;
import com.sdhs.analyze.common.BizConstants;
import com.sdhs.analyze.dao.network.NetworkMapper;
import com.sdhs.analyze.utils.RedisUtil;
import com.sdhs.analyze.utils.StatusCheckUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class NetWorkService {

    @Autowired
    private NetworkMapper networkMapper;

    @Autowired
    private NodeStatusService nodeStatusService;

    @Autowired
    private RedisUtil redisUtil;

    private String split = "|";

    private String redisKeySplit = ":";

    public List<NetWork> selectNetworkList() {
        return networkMapper.selectNetworkList();
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateNewwork(NetWork netWork) {
        networkMapper.updateNewwork(netWork);
    }

    /**
     * 检测门架系统至运行监测系统、门架至省中心、门架至部中心的网络状态
     *
     * @param orgId
     */
    public InfoNodeStatus networkMonitor(
            OrgInfo orgInfo,
            Map<String, InfoNodeStatus> nodeStatusMap,
            Map<String, DicNodeType> nodeTypeMap,
            InfoNodeStatus parentNodeStatus,
            GantryMonitorInfo gantryMonitorInfo) {

        DicNodeType networkNodeType = nodeTypeMap.get(BizConstants.NODE_TYPE_NETWORK);

        InfoNodeStatus netWorkNodeStatus = nodeStatusService.makeNodeStatus(
                networkNodeType,
                orgInfo.getOrgId(),
                orgInfo.getOrgName() + split + networkNodeType.getNodeTypeName(),
                orgInfo.getOrgId(),
                BizConstants.NODE_STATUS_UNKNOWN,
                orgInfo.getOrgId(),
                "",
                new Date(0)
        );

        Date now = new Date();

        /* 获取最新检测信息 */
        List<NetWork> netWorks = networkMapper.selectNetworkByOrgId(orgInfo.getOrgId());

        /* 新状态 */
        List<InfoNodeStatus> newNodeStatus = new ArrayList<>();

        /* 网络状态判定 */
        for (NetWork netWork : netWorks) {
            long timeDiff = 0;
            if (netWork.getStatus() > 0) {
                timeDiff = now.getTime() - netWork.getExcTime().getTime();
            }
            int timeDiffMinute = (int) (timeDiff / 60000.0);
            InfoNodeStatus networkNodeStatus = StatusCheckUtils.checkStatusByThreshold(
                    timeDiffMinute,
                    netWork.getStatusChangeTime(),
                    nodeTypeMap.get(netWork.getNodeType()),
                    netWork.getNodeId(),
                    orgInfo.getOrgName() + split + nodeTypeMap.get(netWork.getNodeType()).getNodeTypeName(),
                    orgInfo.getOrgId(),
                    netWorkNodeStatus);
            newNodeStatus.add(networkNodeStatus);
            if (netWork.getNodeType().equals(BizConstants.NODE_TYPE_NETWORK_MONITOR)) {
                gantryMonitorInfo.getNetworkMonitor().setStatus(networkNodeStatus.getStatus());
                if (networkNodeStatus.getStatus() == BizConstants.NODE_STATUS_NORMAL) {
                    gantryMonitorInfo.getNetworkMonitor().setRemark(String.format("%s",
                            DateFormatUtils.format(netWork.getStatusChangeTime(), "yyyy-MM-dd HH:mm:ss")));
                } else {
                    gantryMonitorInfo.getNetworkMonitor().setRemark(String.format("%s|%s",
                            DateFormatUtils.format(netWork.getStatusChangeTime(), "yyyy-MM-dd HH:mm:ss"),
                            netWork.getExcTime() == null ? "" : DateFormatUtils.format(netWork.getExcTime(), "yyyy-MM-dd HH:mm:ss")));
                }
            } else if (netWork.getNodeType().equals(BizConstants.NODE_TYPE_NETWORK_MINISTRY)) {
                gantryMonitorInfo.getNetworkMinistry().setStatus(networkNodeStatus.getStatus());
                if (networkNodeStatus.getStatus() == BizConstants.NODE_STATUS_NORMAL) {
                    gantryMonitorInfo.getNetworkMinistry().setRemark(String.format("%s",
                            DateFormatUtils.format(netWork.getStatusChangeTime(), "yyyy-MM-dd HH:mm:ss")));
                } else {
                    gantryMonitorInfo.getNetworkMinistry().setRemark(String.format("%s|%s",
                            DateFormatUtils.format(netWork.getStatusChangeTime(), "yyyy-MM-dd HH:mm:ss"),
                            netWork.getExcTime() == null ? "" : DateFormatUtils.format(netWork.getExcTime(), "yyyy-MM-dd HH:mm:ss")));
                }
            } else if (netWork.getNodeType().equals(BizConstants.NODE_TYPE_NETWORK_PROVINCE)) {
                gantryMonitorInfo.getNetworkProvince().setStatus(networkNodeStatus.getStatus());
                if (networkNodeStatus.getStatus() == BizConstants.NODE_STATUS_NORMAL) {
                    gantryMonitorInfo.getNetworkProvince().setRemark(String.format("%s",
                            DateFormatUtils.format(netWork.getStatusChangeTime(), "yyyy-MM-dd HH:mm:ss")));
                } else {
                    gantryMonitorInfo.getNetworkProvince().setRemark(String.format("%s|%s",
                            DateFormatUtils.format(netWork.getStatusChangeTime(), "yyyy-MM-dd HH:mm:ss"),
                            netWork.getExcTime() == null ? "" : DateFormatUtils.format(netWork.getExcTime(), "yyyy-MM-dd HH:mm:ss")));
                }
            }
        }

        for (InfoNodeStatus infoNodeStatus : newNodeStatus) {
            nodeStatusMap.put(infoNodeStatus.getKey(), infoNodeStatus);
        }

        nodeStatusMap.put(netWorkNodeStatus.getKey(), netWorkNodeStatus);

        gantryMonitorInfo.getNetwork().setStatus(netWorkNodeStatus.getStatus());

        /* 判断父节点的状态 */
        StatusCheckUtils.checkParentNodeStatus(netWorkNodeStatus.getStatus(),
                netWorkNodeStatus.getStatusCheckTime(),
                parentNodeStatus);
        return netWorkNodeStatus;
    }

    /**
     * 获得网络连接状态
     *
     * @param nodeId
     * @param nodeType
     * @return
     */
    public NetWork getNetworkStatus(String nodeId, String nodeType) {
        NetWork netWork = null;
        String key = BizConstants.REDIS_KEY_PRE_GANTRY_NETWORK + nodeType + redisKeySplit + nodeId;
        String json = redisUtil.get(key);
        if (json == null) {
            netWork = new NetWork();
            netWork.setStatus(BizConstants.NODE_STATUS_UNKNOWN);
            netWork.setStatusChangeTime(new Date(0));
        }
        netWork = JSON.parseObject(json, NetWork.class);
        return netWork;
    }

}
